// stb风格stack in c
// 
// license: MIT


#ifndef __STACK_H__
#define __STACK_H__

// stack.h

#include <sys/types.h> // cross platform ?
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
typedef struct stack_node_t {
    void* value;
    struct stack_node_t *next;
} stack_node_t;


typedef struct stack_t {
    uint32_t size;
    stack_node_t *head;
} stack_t;

void stack_new(stack_t* stack);

void stack_push(stack_t* stack, void* value);

void* stack_pop(stack_t* stack);

bool stack_empty(stack_t* stack);

void* stack_peek(stack_t* stack);

void stack_free(stack_t* stack);

// end stack.h

#endif // header file protect


#ifdef STACK_IMPLEMENTATION
void stack_new(stack_t * stack) {
    stack->head = NULL;
    stack->size = 0;
}

bool stack_empty(stack_t* stack) {
    return stack->size == 0;
}

void stack_push(stack_t* stack, void* value){
    stack_node_t* node = malloc(sizeof(stack_node_t));
    node->value = value;
    node->next = stack->head;

    stack->head = node;
    stack->size++;
}


void* stack_pop(stack_t* stack){
    if (stack_empty(stack)) {
        return NULL;
    }

    stack_node_t* tmp = stack->head;
    void* value = tmp->value;
    stack->head = stack->head->next;

    free(tmp);

    stack->size--;

    return value;
}



void* stack_peek(stack_t* stack) {
    if(stack_empty(stack)) {
        return NULL;
    }

    return stack->head->value;
}

void stack_free(stack_t* stack) {
    stack_node_t* tmp = stack->head;
    while(tmp) {
        stack_node_t* tmp2 = tmp->next;
        free(tmp);
        tmp = tmp2;
    }
}

#endif // impl